package pos.gui;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.*;
import java.text.ParseException;
import java.util.Collection;
import java.util.Comparator;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import pos.controller.PianiController;
import pos.domain.Corso;
import pos.domain.EccezionePrecondizioni;
import pos.domain.Piano;
import pos.domain.TipoLinkcomposto_da;
import pos.server.dac.exceptions.EccezioneCRUD;

public class PianiView extends VerticalPanel{
    private static HorizontalPanel rootPanel = new HorizontalPanel();
    private static VerticalPanel pianiList = new VerticalPanel();
    private static VerticalPanel corsiInPianoList = new VerticalPanel();
    private static VerticalPanel corsiNonInPianoList = new VerticalPanel();
    private static VerticalPanel boxPanel = new VerticalPanel();

    private static IntegerBox annoBox = new IntegerBox();
    private static IntegerBox semestreBox = new IntegerBox();
    private static TextBox pianoBox;
    
    static TreeSet<Piano> pianiModel = new TreeSet<Piano>(new Comparator<Piano>() {

        @Override
        public int compare(Piano t, Piano t1)
        {
            return t.getNome().compareTo(t1.getNome());
        }
    });
    private static Piano pianoSelezionato = null;

    public PianiView() {           
        boxPanel.clear();
        rootPanel.add(pianiList);
        rootPanel.add(corsiInPianoList);
        rootPanel.add(corsiNonInPianoList);
        rootPanel.add(boxPanel);
        
        add(rootPanel);  
    }
    
    private static class AggiungiCorsoInPiano implements ClickHandler {
        Corso c;
        Piano p;
        public AggiungiCorsoInPiano(Corso c, Piano p) {
            this.c = c;
            this.p = p;
        }

        @Override
        public void onClick(ClickEvent event) {
            try {
                if(annoBox.getValueOrThrow() == null || annoBox.getValueOrThrow() < 1 || (semestreBox.getValueOrThrow() != 1 && semestreBox.getValueOrThrow() != 2)){
                    Window.alert("I dati immessi nel campo Anno o Semestre sono errati");
                    annoBox.setFocus(true);
                    return;
                }
            } catch (ParseException ex) {
                 Window.alert("I dati immessi nel campo Anno o Semestre sono errati");
                 annoBox.setFocus(true);
                 return;
            }
            try {
                PianiController.aggiungiCorsoInPiano(c, p, annoBox.getValue(), semestreBox.getValue());
            } catch (EccezionePrecondizioni ex) {
                Logger.getLogger(PianiView.class.getName()).log(Level.SEVERE, null, ex);
            } catch (EccezioneCRUD ex) {
                Logger.getLogger(PianiView.class.getName()).log(Level.SEVERE, null, ex);
            }
            refreshCorsiDiPiano(p);
        }
        
        
    }
    
    private static class EliminaCorsoDaPianoHandler implements ClickHandler {

        Piano p;
        Corso c;

        public EliminaCorsoDaPianoHandler(Piano p, Corso c) {
            this.p = p;
            this.c = c;
        }

        @Override
        public void onClick(ClickEvent event) {
            try {
                PianiController.eliminaCorsoDaPiano(p, c, Index.getUtente());
            } catch (EccezionePrecondizioni ex) {
                Logger.getLogger(PianiView.class.getName()).log(Level.SEVERE, null, ex);
            } catch (EccezioneCRUD ex) {
                Logger.getLogger(PianiView.class.getName()).log(Level.SEVERE, null, ex);
            }
            refreshCorsiDiPiano(p);
        }
    }
    
    private static class EliminaPianoHandler implements ClickHandler {

        Piano p;
        public EliminaPianoHandler(Piano p) {
            this.p = p;
        }

        @Override
        public void onClick(ClickEvent event) {
            PianiController.eliminaPiano(p);
        }
    }

    public static void refreshPiani() {
        pianiList.clear();
        pianiList.setStyleName("piani");
        for (Piano p : pianiModel) {
            aggiungiPiano(p);
        }
        HorizontalPanel aggiungiPianoPanel = new HorizontalPanel();
        pianoBox = new TextBox();
        pianoBox.setSize("100px", "10px");
        Button addPianoButton = new Button("+");
        aggiungiPianoPanel.add(pianoBox);
        addPianoButton.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                if(pianoBox.getText().isEmpty())
                    return;
                PianiController.aggiungiPiano(pianoBox.getText());
                refreshPiani();
            }
        });
        aggiungiPianoPanel.add(addPianoButton);
        pianiList.add(aggiungiPianoPanel);
    }

    private static void aggiungiPiano(Piano p) {
        HorizontalPanel panel = new HorizontalPanel();
        Label l = new Label(p.getNome());
        l.addClickHandler(new ShowPianoHandler(p));
        l.setStyleName(p.equals(pianoSelezionato) ? "pianoSelezionato" : "piano");
        panel.add(l);
        
        Button eliminaPianoButton = new Button("X");
        eliminaPianoButton.addClickHandler(new EliminaPianoHandler(p));
        panel.setVerticalAlignment(ALIGN_MIDDLE);
        panel.add(eliminaPianoButton);
        pianiList.add(panel);
    }

    static class ShowPianoHandler implements ClickHandler {

        Piano p;

        public ShowPianoHandler(Piano p) {
            this.p = p;
        }

        @Override
        public void onClick(ClickEvent event) {
            pianoSelezionato = p;
            refreshPiani();
            refreshCorsiDiPiano(p);
        }
    }

    public static void refreshCorsiDiPiano(Piano p) {
        corsiInPianoList.clear();
        corsiInPianoList.setStyleName("corsi");
        corsiNonInPianoList.clear();
        corsiNonInPianoList.setStyleName("corsi");
        corsiInPianoList.add(new HTML("<h3>Corsi facenti parte del piano</h3>"));
        corsiNonInPianoList.add(new HTML("<h3>Corsi non facenti parte del piano</h3>"));
        boxPanel.clear();
        boxPanel.setStyleName("boxPanel");
        HorizontalPanel p1 = new HorizontalPanel();
        HorizontalPanel p2 = new HorizontalPanel();

        p1.add(new Label("Anno: "));
        p1.add(annoBox);
        p2.add(new Label("Semestre:"));
        p2.add(semestreBox);
        boxPanel.add(p1);
        boxPanel.add(p2);
        for (TipoLinkcomposto_da link : p.getCorsi()) {
            FlowPanel panel = new FlowPanel();
            Label label = new Label(link.getCorso().getNome() + ": ");
            label.setStyleName("corso");
            Label label2 = new Label(link.getAnno() + "° anno, " + link.getSemestre() +  "° semestre");
            label.addClickHandler(new EliminaCorsoDaPianoHandler(p, link.getCorso()));
            panel.add(label);
            panel.add(label2);
            panel.setStyleName("corsoPanel");
            corsiInPianoList.add(panel);
        }

        Collection<Corso> cnip = PianiController.getAllCorsiNotInPiani(Index.getUtente(), p);
        System.out.println(cnip.toString());
        for (Corso c : cnip) {
            Label l = new Label(c.getNome());
            l.addClickHandler(new AggiungiCorsoInPiano(c,p));
            l.setStyleName("corso");
            corsiNonInPianoList.add(l);
        }
    }
    

    public void setModel(Collection<Piano> model) {
        pianiModel.clear();
        pianiModel.addAll(model);
        refreshPiani();
        System.out.println(model);
    }
    
    public static Collection<Piano> getModel(){
        return pianiModel;
    }
}